package com.am.server.api.system.permission.advice;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.codec.Base64;
import cn.hutool.core.text.CharSequenceUtil;
import com.am.server.api.system.permission.exception.UpdateSuperUserInfoException;
import com.am.server.api.system.permission.service.SuperUserService;
import com.am.server.api.system.permission.service.SystemPermissionService;
import com.am.server.api.system.user.model.dto.LoginDto;
import com.am.server.api.system.user.model.dto.LoginUserInfoDto;
import com.am.server.api.system.user.model.dto.UserInfoDto;
import com.am.server.common.base.model.enumerate.Gender;
import com.am.server.common.base.service.CommonService;
import com.am.server.common.config.SuperUser;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;

import java.util.Arrays;

/**
 * 登录切面
 *
 * @author 阮雪峰
 */
@Aspect
@Component
public record LoginAdvice(CommonService commonService, SystemPermissionService systemPermissionService,
                          SuperUserService superUserService) {

    /**
     * 登录切面，判断是否为超级管理员登录
     *
     * @param pjp pjp
     * @return Object
     */
    @Around("execution(* *..LoginUserService.login(..))")
    public Object login(ProceedingJoinPoint pjp) throws Throwable {
        LoginDto dto = (LoginDto) pjp.getArgs()[0];
        String inputPassword = new String(Base64.decode(dto.getPassword()));
        SuperUser superUser = superUserService.get();
        if (Boolean.TRUE.equals(superUser.getEnable()) && CharSequenceUtil.equals(dto.getUsername(), superUser.getUsername()) && CharSequenceUtil.equals(inputPassword, superUser.getPassword())) {
            StpUtil.login(superUser.getId());
            return new LoginUserInfoDto(StpUtil.getTokenValue());
        } else {
            return pjp.proceed();
        }
    }

    /**
     * 用户信息切面，如果是超级管理员默认赋值
     *
     * @param pjp pjp
     * @return Object
     */
    @Around("execution(* *..LoginUserService.info(..))")
    public Object info(ProceedingJoinPoint pjp) throws Throwable {
        SuperUser superUser = superUserService.get();
        if (Boolean.TRUE.equals(superUser.getEnable()) && commonService.isSupperUser()) {
            return new UserInfoDto()
                    .setId(commonService.getLoginUserId())
                    .setAvatar("https://ruanxuefeng.gitee.io/source/am/admin-avatar.gif")
                    .setEmail("admin@am.com")
                    .setGender(Gender.MALE)
                    .setUsername("超级管理员")
                    .setRoles(Arrays.asList("这管理员", "那管理员"));
        } else {
            return pjp.proceed();
        }
    }

    /**
     * 用户信息切面，如果是超级管理员默认赋值
     *
     * @param pjp pjp
     * @return Object
     */
    @Around("execution(* *..LoginUserService.update(com.am.server.api.system.user.model.dto.UpdateLoginUserInfoDto))")
    public Object updateUserInfo(ProceedingJoinPoint pjp) throws Throwable {
        SuperUser superUser = superUserService.get();
        if (Boolean.TRUE.equals(superUser.getEnable()) && commonService.isSupperUser()) {
            throw new UpdateSuperUserInfoException();
        } else {
            return pjp.proceed();
        }
    }

    /**
     * 用户信息切面，如果是超级管理员默认赋值
     *
     * @param pjp pjp
     * @return Object
     */
    @Around("execution(* *..LoginUserService.getMenuList())")
    public Object menuList(ProceedingJoinPoint pjp) throws Throwable {
        SuperUser superUser = superUserService.get();
        if (Boolean.TRUE.equals(superUser.getEnable()) && commonService.isSupperUser()) {
            return systemPermissionService.getMenuTree();
        } else {
            return pjp.proceed();
        }
    }

    /**
     * 用户信息切面，如果是超级管理员默认赋值
     *
     * @param pjp pjp
     * @return Object
     */
    @Around("execution(* *..UserPermissionCacheService.getPermissionList(..))")
    public Object getPermissionList(ProceedingJoinPoint pjp) throws Throwable {
        SuperUser superUser = superUserService.get();
        if (Boolean.TRUE.equals(superUser.getEnable()) && commonService.isSupperUser()) {
            return systemPermissionService.getAllKeyList();
        } else {
            return pjp.proceed();
        }
    }
}
